from collections import OrderedDict

from django.shortcuts import render

from goods.models import GoodsChannel, SKU


def get_categories():
    # {   对应goods_channel的group_id
    #     "1": { 1序号2序号对应 频道1 手机 相机 数码 频道2 电脑 办公 家用电器
    #         "channels": [
    #             {"id": 1, "name": "手机", "url": "http://shouji.jd.com/"},
    #             {"id": 2, "name": "相机", "url": "http://www.itcast.cn/"}
    #         ],
    #         "sub_cats": [ 代表cat2的 内容
    #             {
    #                 "id": 38,
    #                 "name": "手机通讯",
    #                 "sub_cats": [
    #                     {"id": 115, "name": "手机"},
    #                     {"id": 116, "name": "游戏手机"}
    #                 ]
    #             },
    #             {
    #                 "id": 39,
    #                 "name": "手机配件",
    #                 "sub_cats": [
    #                     {"id": 119, "name": "手机壳"},
    #                     {"id": 120, "name": "贴膜"}
    #                 ]
    #             }
    #         ]
    #     },
    #     "2": {
    #         "channels": [],
    #         "sub_cats": []
    #     }
    # }
    # 1.创建有序字典
    categories = OrderedDict()

    # 2.获取所有的频道 根据对象拿id  sequence代表 序号手机1 相机2 数码2
    channels = GoodsChannel.objects.order_by('group_id', 'sequence')

    # 3.遍历, 拿到每一个频道  每一条记录
    for channel in channels:

        # 4.获取每一个频道的group_id(代表每一个频道的名称)
        group_id = channel.group_id

        # 5 往有序字典中添加整体的机构: group_id--> key   channels&sub_cats ---> value
        if group_id not in categories:#判断id是否在打字典中
            categories[group_id] = {'channels':[], 'sub_cats':[]}

        # 6.获取第一级分类的对象
        cat1 = channel.category #所以cat1代表的是goods_category这个商品类别表

        # 7.往 channels对应的列表中添加字典数据(第一季分类对象有关)
        categories[group_id]['channels'].append({
            'id':cat1.id,
            'name':cat1.name,
            'url':channel.url
        })

        # 8. 根据cat1 获取cat2 直接遍历 #cat2代表所有的二级标题  因为是1级类别,反向外键取2级类别
        for cat2 in cat1.goodscategory_set.all():

            cat2.sub_cats = []

            # 9. 根据cat2 获取cat3 直接遍历  因为是2级类别,反向外键取3级类别
            for cat3 in cat2.goodscategory_set.all():

                # 10 . 把cat3 的内容直接写入cat2所在的列表中
                cat2.sub_cats.append(cat3)

            # 11. 把cat2 扔到 sub_cats
            categories[group_id]['sub_cats'].append(cat2)

    # 12 . 返回
    return categories

def get_breadcrumb(category): #返回面包屑需要的数据
    """
    和商品分类有关 115是三级的级别


    获取面包屑导航
    :param category: 商品类别 第三级对象
    :return: 面包屑导航字典
    """

    # 定义一个字典:
    breadcrumb = dict(
        cat1='',
        cat2='',
        cat3=''
    )
    # 判断 category 是哪一个级别的.
    # 注意: 这里的 category 是 GoodsCategory对象
    if category.parent is None: #1级的父级为空
        # 当前类别为一级类别
        breadcrumb['cat1'] = category#把1级别赋值给cat1
    # 因为当前这个表示自关联表, 所以关联的对象还是自己:
    elif category.goodscategory_set.count() == 0:#三级的下一级别为0
        # 当前类别为三级
        breadcrumb['cat3'] = category
        cat2 = category.parent
        breadcrumb['cat2'] = cat2
        breadcrumb['cat1'] = cat2.parent
    else:
        # 当前类别为二级
        breadcrumb['cat2'] = category
        breadcrumb['cat1'] = category.parent

    return breadcrumb



def get_goods_and_spec(sku_id, request):
    # 获取当前sku的信息
    try:
        sku = SKU.objects.get(id=sku_id)#获取商品表
        sku.images = sku.skuimage_set.all()#根据反向获取图片表，从图片表获取所有图片，把图片赋值给商品的图片属性
    except SKU.DoesNotExist:
        return render(request, '404.html')

    # 面包屑导航信息中的频道
    goods = sku.goods#根据goods外键取到所有商品
    goods.channel = goods.category1.goodschannel_set.all()[0]

    # 构建当前商品的规格键
    # sku_key = [规格1参数id， 规格2参数id， 规格3参数id, ...]
    sku_specs = sku.skuspecification_set.order_by('spec_id')#把排序的结果赋值到sku_specs里面（所有排过序的手机的可能性）
    # sku_specs = sku.specs.order_by('spec_id')
    sku_key = []
    for spec in sku_specs:#把所有排过序的手机的可能性 进行遍历， 获得每一个
        sku_key.append(spec.option.id)#手机的各种选项id，列表里面存的就是 规格id

    # 获取当前商品的所有SKU
    skus = goods.sku_set.all()# 根据spu商品表goods反向取到sku商品表数据 把这一类对应的所有商品取出来

    # 构建不同规格参数（选项）的sku字典
    # spec_sku_map = {
    #     (规格1参数id, 规格2参数id, 规格2参数id, ...): sku_id,
    #     (规格1参数id, 规格2参数id, 规格3参数id, ...): sku_id,
    #     ...
    # }
    '''
    两个遍历循环，把这一类的所有商品挨个拿过来把每一个商品下面什么规格在整理一下，在拿下一个商品把它下面的规格在全部整理一下，
    
     外面循环把这一堆商品里边的每一个商品拿出来，拿出一个以后，根据这个商品获取这个规格，把规格整理到定义key列表中
     再拿取下一个商品，拿到这个商品后，在把这个商品的规格全部整理一下 ，放到key列表中，再拿取下一个商品
     把所有内容放到外面spec_sku_map = {}这个字典里面
     '''
    spec_sku_map = {}#这个字段里面元组充当key，对应的值sku_id
    for s in skus:#遍历 把这一类对应的每一个商品取出来
        # 获取sku的规格参数
        s_specs = s.skuspecification_set.order_by('spec_id')#取出每一个商品后，获取每一个商品的规格，按照spec_id排序
        # s_specs = s.specs.order_by('spec_id')
        # 用于形成规格参数-sku字典的键
        key = []
        for spec in s_specs:#对排完序的在遍历一下 ，取出
            key.append(spec.option.id)#在把商品的规格id赋值到key中
        # 向规格参数-sku字典添加记录
        spec_sku_map[tuple(key)] = s.id

    # 获取当前商品的规格信息
    # specs = [
    #    {
    #        'name': '屏幕尺寸',
    #        'options': [
    #            {'value': '13.3寸', 'sku_id': xxx},
    #            {'value': '15.4寸', 'sku_id': xxx},
    #        ]
    #    },
    #    {
    #        'name': '颜色',
    #        'options': [
    #            {'value': '银色', 'sku_id': xxx},
    #            {'value': '黑色', 'sku_id': xxx}
    #        ]
    #    },
    #    ...
    # ]
    goods_specs = goods.goodsspecification_set.order_by('id')
    # goods_specs = goods.specs.order_by('id')
    # 若当前sku的规格信息不完整，则不再继续
    if len(sku_key) < len(goods_specs):
        return
    for index, spec in enumerate(goods_specs):
        # 复制当前sku的规格键
        key = sku_key[:]
        # 该规格的选项
        spec_options = spec.specificationoption_set.all()
        # spec_options = spec.options.all()
        for option in spec_options:
            # 在规格参数sku字典中查找符合当前规格的sku
            key[index] = option.id
            option.sku_id = spec_sku_map.get(tuple(key))

        # spec.options = spec_options
        spec.spec_options = spec_options

    data = {
        'goods':goods,
        'goods_specs':goods_specs,
        'sku':sku
    }

    return data